import base64

from Crypto.Cipher import DES
from Crypto.Util.Padding import pad, unpad

'''
DES工具类：使用ECB模式加密，pkcs7格式的padding
'''
class DESUtil:
    # 使用ECB模式加密
    MODE = DES.MODE_ECB
    # 使用默认的pkcs7 padding
    PAD_STYLE = 'pkcs7'
    ENCODING = 'UTF-8'

    # key长度只能为8，对应DES-64
    @staticmethod
    def encrypt(plaintext: str, key: str) -> str:
       # 直接截取前8个字符作为密钥，与JS版本行为一致
        if len(key) > 8:
            key = key[:8]
        elif len(key) < 8:
            key = key.ljust(8, '\0')  # 不足8位时右补零
        # 将密钥编码为UTF-8格式的bytes
        key_bytes = key.encode(DESUtil.ENCODING)

        # 创建DES对象
        cipher = DES.new(key_bytes, DESUtil.MODE)
        # 将明文编码为UTF-8格式的bytes
        plaintext_bytes = plaintext.encode(DESUtil.ENCODING)
        # 为编码后的明文添加padding
        plaintext_bytes_padded = pad(plaintext_bytes, DES.block_size, DESUtil.PAD_STYLE)
        # 执行加密
        ciphertext_bytes = cipher.encrypt(plaintext_bytes_padded)
        # 将加密后的bytes进行base64编码
        ciphertext_base64_bytes = base64.b64encode(ciphertext_bytes)
        # 将base64编码过的bytes，解码为Python中使用的字符串类型（即unicode字符串）
        ciphertext = ciphertext_base64_bytes.decode(DESUtil.ENCODING)
        return ciphertext

    @staticmethod
    def decrypt(ciphertext: str, key: str) -> str:
        # 直接截取前8个字符作为密钥，与JS版本行为一致
        if len(key) > 8:
            key = key[:8]
        elif len(key) < 8:
            key = key.ljust(8, '\0')  # 不足8位时右补零
        # 将密钥编码为UTF-8格式的bytes
        key_bytes = key.encode(DESUtil.ENCODING)
        # 创建DES对象
        decrypter = DES.new(key_bytes, DESUtil.MODE)
        # 将密文编码为UTF-8格式的（同时也是base64编码的）bytes
        ciphertext_base64_bytes = ciphertext.encode(DESUtil.ENCODING)
        # 将base64编码的bytes，解码为原始的密文bytes
        ciphertext_bytes = base64.b64decode(ciphertext_base64_bytes)
        # 解码为明文
        plaintext_bytes_padded = decrypter.decrypt(ciphertext_bytes)
        # 去掉Padding
        plaintext_bytes = unpad(plaintext_bytes_padded, DES.block_size, DESUtil.PAD_STYLE)
        # 将UTF-8格式编码的明文bytes，解码为Python中的字符串类型（即unicode字符串）
        plaintext = plaintext_bytes.decode(DESUtil.ENCODING)
        return plaintext